package xman.mssh.hibernate;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import xman.mssh.hibernate.entity.CMBCard;
import xman.mssh.hibernate.entity.ICBCCard;
import xman.mssh.hibernate.entity.JpaEntity;
import xman.mssh.hibernate.entity.Many2ManyEntity;
import xman.mssh.hibernate.entity.Many2ManyMappedEntity;
import xman.mssh.hibernate.entity.One2OneEntity;
import xman.mssh.hibernate.entity.One2OneMappedEntity;
import xman.mssh.hibernate.entity.OneManyEntity;
import xman.mssh.hibernate.entity.OneManyMappedEntity;
import xman.mssh.hibernate.entity.OneReferEntity;
import xman.mssh.hibernate.service.RepositoryService;
import xman.mssh.util.DateUtil;
import xman.mssh.util.HTTPLongClient;

import com.alibaba.fastjson.JSONObject;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/spring-*.xml" })
public class JpaSpring {
    
    private static Logger logger = LoggerFactory.getLogger(JpaSpring.class);
    
    @Resource
    private EntityManagerFactory entityManagerFactory;
    
    @Resource
    private RepositoryService repositoryService;
    
    protected HTTPLongClient httpLongClientInstance = HTTPLongClient.newInstance();
    
    {
        httpLongClientInstance.setConnectTimeout(1000);
        httpLongClientInstance.setSoTimeout(3000);
        httpLongClientInstance.reInit();
    }
    
    @Test
    public void multi() {
        LinkedList<String> sqls = new LinkedList<String>();
        sqls.add("insert into tb_jpa('descr) values('multi')");
        repositoryService.multiTransactionJDBCHandler(sqls);
    }
    
    @Test
    public void emf() {
        try {
            EntityManager em = entityManagerFactory.createEntityManager();
            em.getTransaction().begin();
            JpaEntity jpa = new JpaEntity();
            jpa.setDescr("emf");
            em.merge(jpa);
            em.getTransaction().commit();
            em.close();
        } catch (Throwable e) {
            e.printStackTrace();
        }

    }
    
    @Test
    public void jpa() {
        JpaEntity jpa = new JpaEntity();
        jpa.setId(1);
        jpa.setDescr("jpa");
        repositoryService.merge(jpa);
        
        JpaEntity ret = repositoryService.get(JpaEntity.class, 1);
        logger.info("{}", JSONObject.toJSON(ret));
    }
    
    @Test
    public void o2o() {
        OneReferEntity ref = new OneReferEntity();
        One2OneEntity one = new One2OneEntity();
        one.setDescr("one2one");
        One2OneMappedEntity oneMapped = new One2OneMappedEntity();
        oneMapped.setDescr("one2one");
        OneManyEntity many = new OneManyEntity();
        many.setDescr("one2one");
        OneManyMappedEntity manyMapped = new OneManyMappedEntity();
        manyMapped.setDescr("one2one");
        
        ref.setOne(one);
        ref.setOneMapped(oneMapped);
        ref.setMany(many);
        ref.setManyMapped(manyMapped);
        
        repositoryService.merge(ref);
    }
    
    @Test
    public void m2m() {
        Many2ManyEntity refer = new Many2ManyEntity();
        refer.setDescr("ref");
        Set<Many2ManyMappedEntity> set = new HashSet<Many2ManyMappedEntity>();
        Many2ManyMappedEntity oentity = new Many2ManyMappedEntity();
        oentity.setDescr("default");
        set.add(oentity);
        for (int i = 0; i < 3; i++) {
            Many2ManyMappedEntity entity = new Many2ManyMappedEntity();
            entity.setDescr(String.valueOf(i));
            set.add(entity);
        }
        refer.setMapped(set);
        repositoryService.persisit(refer);
    }
    
    @Test
    public void m2mr() {
        Many2ManyEntity e = new Many2ManyEntity();
        e.setDescr("mappedRef");
        Set<Many2ManyEntity> mappedRef = new HashSet<Many2ManyEntity>();
        mappedRef.add(e);
        Many2ManyMappedEntity mapped = new Many2ManyMappedEntity();
        mapped.setDescr("mapped");
        mapped.setRefer(mappedRef);
        
        repositoryService.persisit(mapped);
    }
    
    public void finance() throws Exception {
        BufferedReader br = null;
        String line = null;
        String split = null;
        try {
            String str = "D:\\Users\\usr\\Desktop\\1";
            File file = new File(str);
            FileReader fr = new FileReader(file);
            br = new BufferedReader(fr);
            while ((line = br.readLine()) != null) {
                StringUtils.split(line, split);
            }
        } finally {
            br.close();
        }
    }
    
    public ICBCCard icbc(String[] strs) {
        ICBCCard icbc = new ICBCCard();
        icbc.setCtime(DateUtil.stringToDate(StringUtils.trim(strs[0]), DateUtil.DATE_FORMAT));
        icbc.setDescription(StringUtils.trim(strs[1]));
        icbc.setPlace(StringUtils.trim(strs[2]));
        icbc.setCin(StringUtils.isEmpty(StringUtils.trim(strs[3])) ? null : new BigDecimal(StringUtils.trim(strs[3])));
        icbc.setCout(StringUtils.isEmpty(StringUtils.trim(strs[4])) ? null : new BigDecimal(StringUtils.trim(strs[4])));
        icbc.setCurrency(StringUtils.trim(strs[5]));
        icbc.setCret(StringUtils.isEmpty(StringUtils.trim(strs[6])) ? null : new BigDecimal(StringUtils.trim(strs[6])));
        return icbc;
    }
    
    public CMBCard cmb(String[] strs) {
        CMBCard cmb = new CMBCard();
        cmb.setCardId(StringUtils.trim(strs[0]));
        cmb.setCtime(DateUtil.stringToDate(StringUtils.trim(strs[1]), DateUtil.DATE_FORMAT));
        cmb.setCurrency(StringUtils.trim(strs[2]));
        cmb.setCout(StringUtils.isEmpty(StringUtils.trim(strs[3])) ? null : new BigDecimal(StringUtils.trim(strs[3])));
        cmb.setCin(StringUtils.isEmpty(StringUtils.trim(strs[4])) ? null : new BigDecimal(StringUtils.trim(strs[4])));
        cmb.setCret(StringUtils.isEmpty(StringUtils.trim(strs[5])) ? null : new BigDecimal(StringUtils.trim(strs[5])));
        cmb.setDescription(StringUtils.trim(strs[6]));
        return cmb;
    }
}
